/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainFrame.java
 *
 * Created on Jan 14, 2013, 5:23:24 PM
 */
package view;

/**
 *
 * @author BLACK
 */
import controller.ClientController;
import dto.Account;
import dto.Message;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.rmi.RemoteException;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

public class MainFrame extends javax.swing.JFrame {

    private Account account;
    private ClientController clientController;
    private ContactTree ct;
    private int windowID;
    private JTree contactTree;
    private Account memberToChat;
    private Vector<Account> contactList;

    public MainFrame(String mail, ClientController theClientController) {
        this.clientController = theClientController;
//        contactList=new Vector<>();
        initComponents();
        setTitle(mail);
        
        /**
         * SendMailJMenuItem is for sending mails. that will open sendMailForm that take
         * Receiver mail & Title & message to send them.
         */

        SendMailjMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                SendMailForm sendmail = new SendMailForm(account.getEmail());
                sendmail.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
                sendmail.setVisible(true);
            }
        });

        /**
         * AddContactMenuItem to Add new contact to user's contact list.
         */
        AddContactMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ev) {
                AddContact addContactFrame = new AddContact(MainFrame.this, clientController);
                addContactFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
                addContactFrame.setVisible(true);

            }
        });

        /**
         * DeleteContactMenuItem to delete contact from user's contact List.
         */
        DeleteContactjMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ev) {

                DeleteContact deleteContactFrame = new DeleteContact(MainFrame.this, clientController);
                deleteContactFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
                deleteContactFrame.setVisible(true);
            }
        });

        /**
         * LogOutjMenuItem .. Allow user to log out & inform server & other user about that.
         */
        LogOutjMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                    jMenuItem4ActionPerformed(e);
            }
        });

        /**
         * Close mainFrame Window [X]
         * make the same action of jMenuItem4 [log out.]
         */
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                LogOutjMenuItem.doClick();
            }
        });
//        account = clientController.getLoggedInAccount();
//        String status = account.getStatus().toLowerCase();
//        status = status.replace(status.charAt(0), String.valueOf(status.charAt(0)).toUpperCase().charAt(0));
//        statusComboBox.setSelectedItem(status);
        /*
         * ************* show ContactList in Frame *************
         */
        
        /**
         * Thread checkFriendRequestThread check if there're pinned Friend Requests. 
         */
        Thread checkFriendRequestThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    ClientController.getService().checkPinnedFriendRequest(clientController.getClientService());
                } catch (RemoteException ex) {
                    ex.printStackTrace();
                }
            }
        });

        checkFriendRequestThread.start();

        /**
         * Thread checkFriendRequestReplyThread check if there're pinned Friend Requests Replies.  
         */
        Thread checkFriendRequestReplyThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    ClientController.getService().checkPinnedFriendRequestReply(clientController.getClientService());
                } catch (RemoteException ex) {
                    ex.printStackTrace();
                }
            }
        });
        checkFriendRequestReplyThread.start();
        /**
         * ************* show ContactList in Frame *************
         */
        clientController.setActiveWindow(this);
        this.renderContactList();

        showOfflineMessages();
    }


    /**
     * Method to show user's contact list .. it gets the list from DB, put it on Tree 
     * with to mail branches [online/offline] then show it on the Frame after cheching everybody's state [Busy/Away/..etc].
     */
    public void renderContactList() {
        try {
            contactList = ClientController.getService().getContactList(clientController.getClientService());
            System.out.println("Contact_List_Size"+contactList.size());
            clientController.getLoggedInAccount().setContactList(contactList);
            ct = new ContactTree(contactList);
            ct.setClientController(clientController);
            contactTree = ct.getContactTree();

            if (contactTree == null) {
                System.out.println("Tree is Empty.");
            }

            jScrollPane1.setViewportView(contactTree);

            if (contactTree != null) {
                contactTree.addMouseListener(ml);
            }
            this.pack();
        } catch (RemoteException ex) {
            ex.printStackTrace();
        }

    }
    MouseListener ml = new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            int selRow = contactTree.getRowForLocation(e.getX(), e.getY());
            //System.out.println(contactTree.getEditingPath());
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) contactTree.getLastSelectedPathComponent();
            if (selRow != -1) {
                if (e.getClickCount() == 1) {
                } else if (e.getClickCount() == 2) {
                    if (node != null) {
                        try {
                            System.out.println("Loggedin Account" + clientController.getLoggedInAccount());
                            memberToChat = (Account) node.getUserObject();
                            System.out.println(memberToChat);
                            clientController.newChatRoom(memberToChat);
                        } catch (RemoteException ex) {
                            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }
    };

    /**
     * send ClientController reference. 
     */           
    public ClientController sendClientController() {
        return clientController;
    }

    /**
     * Creates new form MainFrame
     */
    
    /**
     * send ClientController reference.
     * 
     */
    public Vector<Account> sendContactList() {
        return contactList;
    }

    /**
     * Creates new form MainFrame
     */
    public MainFrame() {
        initComponents();

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jMenuItem1 = new javax.swing.JMenuItem();
        jPopupMenu1 = new javax.swing.JPopupMenu();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();
        statusComboBox = new javax.swing.JComboBox();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel2 = new javax.swing.JPanel(new CardLayout());
        jScrollPane2 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jLabel1 = new javax.swing.JLabel();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        LogOutjMenuItem = new javax.swing.JMenuItem();
        jMenu2 = new javax.swing.JMenu();
        AddContactMenuItem = new javax.swing.JMenuItem();
        DeleteContactjMenuItem = new javax.swing.JMenuItem();
        jMenu3 = new javax.swing.JMenu();
        SendMailjMenuItem = new javax.swing.JMenuItem();

        jMenuItem1.setText("jMenuItem1");

        jMenuItem2.setText("jMenuItem2");

        jMenuItem3.setText("jMenuItem3");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        statusComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Online", "Busy", "Away", "Offline" }));
        statusComboBox.setRenderer(new StatusListCellRenderer());
        statusComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                statusComboBoxActionPerformed(evt);
            }
        });

        jSplitPane1.setDividerLocation(200);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

        jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Contacts:", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Times New Roman", 0, 14), new java.awt.Color(102, 102, 102))); // NOI18N
        jScrollPane1.setName(""); // NOI18N
        jSplitPane1.setTopComponent(jScrollPane1);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Announcements:", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Times New Roman", 0, 14), java.awt.Color.darkGray)); // NOI18N

        jTextArea1.setColumns(20);
        jTextArea1.setEditable(false);
        jTextArea1.setLineWrap(true);
        jTextArea1.setRows(5);
        jTextArea1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jScrollPane2.setViewportView(jTextArea1);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
        );

        jSplitPane1.setRightComponent(jPanel2);

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/man-icon.png"))); // NOI18N

        jMenu1.setText("Messenger");

        LogOutjMenuItem.setText("Log out");
        jMenu1.add(LogOutjMenuItem);

        jMenuBar1.add(jMenu1);

        jMenu2.setText("Contacts");

        AddContactMenuItem.setText("Add Contact");
        jMenu2.add(AddContactMenuItem);

        DeleteContactjMenuItem.setText("Delete Contact");
        jMenu2.add(DeleteContactjMenuItem);

        jMenuBar1.add(jMenu2);

        jMenu3.setText("Action");

        SendMailjMenuItem.setText("Send Mail");
        SendMailjMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SendMailjMenuItemActionPerformed(evt);
            }
        });
        jMenu3.add(SendMailjMenuItem);

        jMenuBar1.add(jMenu3);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSplitPane1)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(statusComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(19, 19, 19)
                        .addComponent(statusComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 340, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void statusComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_statusComboBoxActionPerformed
        try {
            String status = statusComboBox.getSelectedItem().toString().toUpperCase();
            clientController.getLoggedInAccount().setStatus(status);
            ClientController.getService().setStatus(status, clientController.getClientService());
        } catch (RemoteException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_statusComboBoxActionPerformed

    private void SendMailjMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SendMailjMenuItemActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_SendMailjMenuItemActionPerformed

    private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            clientController.closeAll();
            clientController.getAccountSession().logout();
        } catch (RemoteException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void showOfflineMessages() {
        final Vector<Message> offlineMessages = clientController.getOfflineMessages();
        ChatWindow chatWindow = null;
        if (offlineMessages != null && !offlineMessages.isEmpty()) {
            for (int i = 0; i < offlineMessages.size(); i++) {
                Message message = offlineMessages.get(i);
                try {
                    if(i == 0 || !offlineMessages.get(i-1).getFrom().equals(offlineMessages.get(i).getFrom()))
                        chatWindow = clientController.newChatRoom(message.getFrom());
                    chatWindow.appendMessage(message);
                } catch (RemoteException ex) {
                    Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    public void notifyStatusChanged(Account account) {
        ct.setStatus(account);
    }

    class StatusListCellRenderer extends DefaultListCellRenderer {

        JLabel lbl = new JLabel();

        @Override
        public Component getListCellRendererComponent(JList list,
                Object value, int index, boolean isSelected,
                boolean cellHasFocus) {
            lbl.setText((String) value);
            Icons icons = new Icons();
            if (value.equals("Online")) {
                lbl.setIcon(icons.getOnlineIcon());
            } else if (value.equals("Away")) {
                lbl.setIcon(icons.getAwayIcon());
            } else if (value.equals("Busy")) {
                lbl.setIcon(icons.getBusyIcon());
            } else if (value.equals("Offline")) {
                lbl.setIcon(icons.getOfflineIcon());
            }
            if (isSelected) {
                lbl.setBackground(new Color(224, 232, 255));
            } else {
                lbl.setBackground(Color.white);
            }
            return lbl;
        }
    }

    /**
     * method to show Announcements that user gets from server.
     */
    public void setAnnouncement(final String Announcement) {

        jTextArea1.setText("\n" + Announcement);
        jTextArea1.repaint();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }


        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MainFrame().setVisible(true);
            }
        });
    }

    /**
     * @return the windowID
     */
    public int getWindowID() {
        return windowID;
    }

    /**
     * @param windowID the windowID to set
     */
    public void setWindowID(int windowID) {
        this.windowID = windowID;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem AddContactMenuItem;
    private javax.swing.JMenuItem DeleteContactjMenuItem;
    private javax.swing.JMenuItem LogOutjMenuItem;
    private javax.swing.JMenuItem SendMailjMenuItem;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenu jMenu3;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPopupMenu jPopupMenu1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JComboBox statusComboBox;
    // End of variables declaration//GEN-END:variables
}
